package cn.zswltech.gruul.biz.service.impl;


import cn.hutool.core.util.ObjectUtil;
import cn.zswltech.gruul.biz.comparator.CustomTreeDOComparator;
import cn.zswltech.gruul.biz.comparator.JsonObjectComparator;
import cn.zswltech.gruul.biz.service.CustomTreeService;
import cn.zswltech.gruul.biz.service.OrgService;
import cn.zswltech.gruul.biz.service.RoleService;
import cn.zswltech.gruul.biz.support.impl.IServiceImpl;
import cn.zswltech.gruul.common.constant.CustomTreeConstants;
import cn.zswltech.gruul.common.constant.MenuConstants;
import cn.zswltech.gruul.common.constant.SystemConstant;
import cn.zswltech.gruul.common.dal.dao.*;
import cn.zswltech.gruul.common.dto.*;
import cn.zswltech.gruul.common.entity.*;
import cn.zswltech.gruul.common.exception.CommonErrorEnum;
import cn.zswltech.gruul.common.exception.MenuErrorEnum;
import cn.zswltech.gruul.common.exception.MenuException;
import cn.zswltech.gruul.common.result.MSG;
import cn.zswltech.gruul.common.result.Response;
import cn.zswltech.gruul.common.util.JSONUtil;
import cn.zswltech.gruul.web.api.util.GruulUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.support.ManagedSet;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.util.Sqls;

import javax.annotation.Resource;
import java.awt.*;
import java.util.*;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;


@Slf4j
@Service("customTreeService")
public class CustomTreeServiceImpl extends IServiceImpl<CustomTreeDO> implements CustomTreeService {
    private final static Logger logger = LoggerFactory.getLogger(CustomTreeServiceImpl.class);
    @Autowired
    private CustomTreeDOMapper customTreeDOMapper;
    @Autowired
    private CustomTreeMenuRefDOMapper customTreeMenuRefDOMapper;
    @Autowired
    private OrgMenuFunctionDOMapper orgMenuFunctionDOMapper;
    @Autowired
    private RoleMenuFunctionDOMapper roleMenuFunctionDOMapper;
    @Autowired
    private MenuDOMapper menuDOMapper;
    @Autowired
    private FunctionDOMapper functionDOMapper;
    @Autowired
    private ResourceDOMapper resourceDOMapper;
    @Resource(name = "orgService")
    private OrgService orgService;
    @Resource(name = "roleService")
    private RoleService roleService;


    @Override
    public Response<List<CustomTreeDO>> getCustomTreeList() {
        Response<List<CustomTreeDO>> response = new Response<>();
        List<CustomTreeDO> customTreeDOs = null;
        try {
            customTreeDOs = customTreeDOMapper.selectAll();
            if (CollectionUtils.isEmpty(customTreeDOs)) {
                response.setCode(SystemConstant.CUSTOMTREE_NO_EXIST);
                response.setMessage(MSG.req_error_customtree_not_exist);
                return response;
            }
        } catch (Exception e) {
            logger.error("API get customTree list error", e);
            response.setMessage(MSG.req_error_query_failed);
            return response;
        }
        if (!customTreeDOs.isEmpty()) {
            for (CustomTreeDO customTreel2 : customTreeDOs) {
                List<CustomTreeMenuRefDO> ml3List = customTreeMenuRefDOMapper.queryByCustomTreeIdView(customTreel2.getId());
                if (ml3List != null && !ml3List.isEmpty()) {
                    customTreel2.setChildren(ml3List);
                }
            }
            // 根据sort排序
            Collections.sort(customTreeDOs, new CustomTreeDOComparator());
        }
        return Response.success(customTreeDOs);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Response deleteCustomTree(Long id) {
        Response response = new Response();
        if (id == null) {
            response.setMessage(MSG.req_error_param_null, "id");
            return response;
        }
        try {
            delByGroup(id);
            return Response.success(null);
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            logger.error("API delete customTree error", e);
            response.setMessage(MSG.req_error_delete_failed);
        }
        return response;
    }


    /**
     * 删除分组
     *
     * @param id
     * @throws Exception
     */
    @Transactional(rollbackFor = Exception.class)
    public void delByGroup(Long id) throws Exception {
        // 删除分组
        customTreeDOMapper.deleteByPrimaryKey(id);
        // 查出所有关联的菜单
        List<CustomTreeMenuRefDO> customTreeMenuRefDOs = customTreeMenuRefDOMapper.queryByCustomTreeIdView(id);
        if (CollectionUtils.isNotEmpty(customTreeMenuRefDOs)) {
            for (CustomTreeMenuRefDO customTreeMenuRefDO : customTreeMenuRefDOs) {
                Long menuId = customTreeMenuRefDO.getId();
                // 删除机构和菜单关联关系
                orgService.deleteOrgMenuFunctions(null, menuId, CustomTreeConstants.OPT_TYPE_MENU, null);
                // 删除角色和菜单关联关系
                roleService.deleteRoleMenuFunctions(null, menuId, CustomTreeConstants.OPT_TYPE_MENU, null);
            }
        }
        // 删除分组和菜单的关联关系
        customTreeMenuRefDOMapper.deleteByCustomTreeId(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Response updateCustomTree(CustomTreeDO customTreeDO) {
        Response response = new Response();
        if (customTreeDO.getId() == null) {
            response.setMessage(MSG.req_error_param_null, "uuid");
            return response;
        }
        if (customTreeDO.getFlag() != null && (customTreeDO.getFlag() != 0 && customTreeDO.getFlag() != 1)) {
            response.setMessage(MSG.req_error_param_tip, "flag", "[0,1]");
            return response;
        }
        if (customTreeDO.getName() != null && StringUtils.isBlank(customTreeDO.getName())) {
            response.setMessage(MSG.req_error_param_null, "name");
            return response;
        }
        if (customTreeDO.getEnName() != null && StringUtils.isBlank(customTreeDO.getEnName())) {
            response.setMessage(MSG.req_error_param_null, "enName");
            return response;
        }
        if (customTreeDO.getIcon() != null && StringUtils.isBlank(customTreeDO.getIcon())) {
            response.setMessage(MSG.req_error_param_null, "icon");
            return response;
        }
        if (customTreeDO.getCode() != null && StringUtils.isBlank(customTreeDO.getCode())) {
            response.setMessage(MSG.req_error_param_null, "code");
            return response;
        }
        try {
            customTreeDO.setGmtModified(new Date());
            updateNotNull(customTreeDO);
            return Response.success(null);
        } catch (Exception e) {
            logger.error("API update customTree error", e);
            response.setMessage(MSG.req_error_modify_failed);
        }
        return response;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Response<Map> createCustomTreeMenu(String params) {
        Response response = new Response();
        if (StringUtils.isBlank(params)) {
            response.setMessage(MSG.req_error_param_null, "params");
            return response;
        }
        try {
            JSONArray jsonArray = JSONUtil.parseArray(params);
            if (CollectionUtils.isEmpty(jsonArray)) {
                response.setMessage(MSG.req_error_param_null, "params");
                return response;
            }
            int size = jsonArray.size();
            Date time = new Date();
            // 遍历自定义分组
            for (int i = 0; i < size; i++) {
                JSONObject jsonObject = jsonArray.getJSONObject(i);
                Long customTreeId = jsonObject.getLong("customTreeId");
                JSONArray menus = jsonObject.getJSONArray("menuList");
                CustomTreeDO query = new CustomTreeDO();
                query.setId(customTreeId);
                CustomTreeDO customTreeIndb = this.selectOne(query);
                if (customTreeIndb == null) {
                    continue;
                }
                // 查出自定义分组下关联的所有菜单
                List<CustomTreeMenuRefDO> customTreeMenuRefDOs = customTreeMenuRefDOMapper.queryByCustomTreeId(customTreeId);
                List<Long> menuAddList = new ArrayList();
                List<Long> menuDeleteList = new ArrayList();
                if (CollectionUtils.isNotEmpty(menus)) {
                    for (int j = 0; j < menus.size(); j++) {
                        boolean contains = false;
                        if (CollectionUtils.isNotEmpty(customTreeMenuRefDOs)) {
                            for (CustomTreeMenuRefDO customTreeMenuRefDO : customTreeMenuRefDOs) {
                                if (menus.getLong(j).equals(customTreeMenuRefDO.getMenuId())) {
                                    contains = true;
                                }
                            }
                        }
                        if (!contains) {
                            menuAddList.add(menus.getLong(j));
                        }
                    }
                }
                List<Long> ids = menus.toJavaList(Long.class);
                for (CustomTreeMenuRefDO customTreeMenuRefDO : customTreeMenuRefDOs) {
                    if (CollectionUtils.isNotEmpty(menus)) { // 原来列表有,现在列表没有的,是要删除的菜单
                        if (!ids.contains(customTreeMenuRefDO.getMenuId())) {
                            menuDeleteList.add(customTreeMenuRefDO.getMenuId());
                        }
                    } else { // 传进来的目录列表为空,删除所有的菜单
                        menuDeleteList.add(customTreeMenuRefDO.getMenuId());
                    }
                }
                // 新增
                if (CollectionUtils.isNotEmpty(menuAddList)) {
                    for (Long menuId : menuAddList) {
                        CustomTreeMenuRefDO customTreeMenuRefDO = new CustomTreeMenuRefDO();
                        customTreeMenuRefDO.setCustomTreeId(customTreeId);
                        customTreeMenuRefDO.setMenuId(menuId);
                        customTreeMenuRefDO.setGmtCreate(time);
                        customTreeMenuRefDO.setGmtModified(time);
                        customTreeMenuRefDO.setSortNo(0);
                        customTreeMenuRefDOMapper.insert(customTreeMenuRefDO);
                    }
                }
                // 删除
                if (CollectionUtils.isNotEmpty(menuDeleteList)) {
                    deleteCustomTreeMenuRef(customTreeId, menuDeleteList);
                }

                Date date = new Date();
                // 排序分组
                customTreeIndb.setSortNo(i + 1);
                customTreeIndb.setGmtModified(date);
                updateNotNull(customTreeIndb);

                // 排序菜单
                if (CollectionUtils.isNotEmpty(menus)) {
                    for (int j = 0; j < menus.size(); j++) {
                        Long menuId = menus.getLong(j);
                        // 排序分组菜单关联表
                        CustomTreeMenuRefDO customTreeMenuRefQuery = new CustomTreeMenuRefDO();
                        customTreeMenuRefQuery.setCustomTreeId(customTreeId);
                        customTreeMenuRefQuery.setMenuId(menuId);
                        customTreeMenuRefQuery.setSortNo(j + 1);
                        customTreeMenuRefQuery.setGmtModified(date);
                        tk.mybatis.mapper.entity.Example example = new Example(CustomTreeMenuRefDO.class);
                        Example.Criteria criteria = example.createCriteria();
                        criteria.andEqualTo("customTreeUuid", customTreeId);
                        criteria.andEqualTo("menuId", menuId);
                        customTreeMenuRefDOMapper.updateByExampleSelective(customTreeMenuRefQuery, example);
                        // 排序菜单表
                        MenuDO menuQuery = new MenuDO();
                        menuQuery.setId(menuId);
                        menuQuery.setSortNo(j + 1);
                        menuQuery.setGmtModified(date);
                        menuDOMapper.update(menuQuery);
                    }
                }
            }
            return Response.success(null);
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            logger.error("API create customTree menu error", e);
            if (e.getMessage().contains("uk_")) {
                return Response.error(MSG.req_error_param_code_repeat);
            }
            response.setMessage(MSG.req_error_create_failed);
        }
        return response;
    }

    @Transactional(rollbackFor = Exception.class)
    public void deleteCustomTreeMenuRef(Long customTreeId, List<Long> menuDeleteList) throws Exception {
        // 删除机构(角色)下关联的菜单
        for (Long menuId : menuDeleteList) {
            customTreeMenuRefDOMapper.deleteByCustomTreeMenuId(customTreeId, menuId);
            OrgMenuFunctionDO orgMenuFunctionDO = new OrgMenuFunctionDO();
            orgMenuFunctionDO.setMenuId(menuId);
            orgMenuFunctionDO.setCustomTreeId(customTreeId);
            List<Long> orgids = orgMenuFunctionDOMapper.getOrgIds(orgMenuFunctionDO);
            if (CollectionUtils.isNotEmpty(orgids)) {
                for (Long orgId : orgids) {
                    orgService.deleteOrgMenuFunctions(orgId, menuId, CustomTreeConstants.OPT_TYPE_MENU, null);
                }
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Response<Map> createCustomTree(CustomTreeDO customTreeDO) {
        Response response = new Response();
        if (checkParams(customTreeDO, response)) {
            return response;
        }
        if (customTreeDO.getParentId() != null) {
            CustomTreeDO customTreeIndb = customTreeDOMapper.selectByPrimaryKey(customTreeDO.getParentId());
            if (customTreeIndb == null) {
                response.setMessage(MSG.req_error_param_invalid, "parentUuid");
                return response;
            }
        }
        try {
            customTreeDOMapper.insert(customTreeDO);
            response.setMessage(MSG.req_error_create_success);
            return Response.success(genParamsMap("id", customTreeDO.getId()));
        } catch (Exception e) {
            logger.error("API create customTree error", e);
            if (e.getMessage().contains("uk_")) {
                return Response.error(MSG.req_error_param_code_repeat);
            }
            response.setMessage(MSG.req_error_create_failed);
        }
        return response;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Response menuSort(Long groupId, String menuIds) {
        Response response = new Response();
        if (groupId == null) {
            response.setMessage(MSG.req_error_param_null, "groupId");
            return response;
        }
        if (StringUtils.isBlank(menuIds)) {
            response.setMessage(MSG.req_error_param_null, "menuIds");
            return response;
        }
        try {
            JSONArray jsonArray = JSONUtil.parseArray(menuIds);
            if (CollectionUtils.isEmpty(jsonArray)) {
                response.setMessage(MSG.req_error_param_invalid, "menuIds");
                return response;
            }
            // menuId去重
            LinkedHashSet<Long> linkedHashSet = new ManagedSet();
            int size = jsonArray.size();
            for (int i = 0; i < size; i++) {
                linkedHashSet.add(jsonArray.getLong(i));
            }
            int index = 1;
            for (Long menuId : linkedHashSet) {
                CustomTreeMenuRefDO customTreeMenuRefDO = new CustomTreeMenuRefDO();
                customTreeMenuRefDO.setSortNo(index);
                customTreeMenuRefDO.setMenuId(menuId);
                customTreeMenuRefDO.setCustomTreeId(groupId);
                customTreeMenuRefDOMapper.updateSort(customTreeMenuRefDO);
                // 更新菜单的排序
                MenuDO menuDO = new MenuDO();
                menuDO.setId(menuId);
                menuDO.setSortNo(index);
                menuDOMapper.update(menuDO);
                index++;
            }
            return Response.success(null);
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            logger.error("API menu sort error", e);
            response.setMessage(MSG.req_error_menu_sort_failed);
        }
        return response;
    }

    @Override
    public List<DisplayGroupDO> getMenu(Map<Long, DisplayGroupDO> groups) {
        List<DisplayGroupDO> menutree = new ArrayList<>();
        Queue<Long> ids = new LinkedList<>(groups.keySet());
        while (ids.size() > 0){
            Long id = ids.poll();
            DisplayGroupDO groupDO = groups.get(id);
            Long parentId = groupDO.getParentId();
            if (parentId == null) {
                menutree.add(groupDO);
            } else {
                DisplayGroupDO parentMenuVO = groups.get(parentId);
                if (parentMenuVO == null){
                    setParentGroup(parentId,groups);
                    parentMenuVO = groups.get(parentId);
                    ids.offer(parentId);
                }
                if (parentMenuVO.getChildren() == null) {
                    parentMenuVO.setChildren(new ArrayList<>());
                }
                parentMenuVO.getChildren().add(JSON.parseObject(JSON.toJSONString(groupDO)));
            }
        }
        for (DisplayGroupDO groupDO:menutree){
            if (groupDO.getChildren() != null) {
                Collections.sort(groupDO.getChildren(), new JsonObjectComparator());

            }
        }
        return menutree;
    }
    private void setParentGroup(Long parentId,Map<Long, DisplayGroupDO> groups){
        CustomTreeDO customTreeDO = customTreeDOMapper.queryById(parentId);
        DisplayGroupDO dgo = new DisplayGroupDO();
        dgo.setCode(customTreeDO.getCode());
        dgo.setGroupId(customTreeDO.getId());
        dgo.setGroupName(customTreeDO.getName());
        dgo.setEnName(customTreeDO.getEnName());
        dgo.setPath(customTreeDO.getPath());
        dgo.setGmtCreate(customTreeDO.getGmtCreate());
        dgo.setSortNo(customTreeDO.getSortNo());
        dgo.setIcon(customTreeDO.getIcon());
        dgo.setParentId(customTreeDO.getParentId());
        groups.put(parentId,dgo);
    }

    @Override
    public CustomTreeDO queryFirstCustomTreeByFunctionId(Long functionId) {
        Map<Long,CustomTreeDO> idMap = customTreeDOMapper.selectAll().stream().collect(Collectors.toMap(CustomTreeDO::getId, Function.identity(),(k1,k2)->k1));
        CustomTreeDO children = customTreeDOMapper.queryCustomTreeByFunctionId(functionId);
        while(Objects.nonNull(children.getParentId())){
            children = idMap.get(children.getParentId());
        }
        return children;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Response groupSort(String groupIds) {
        Response response = new Response();
        if (StringUtils.isBlank(groupIds)) {
            response.setMessage(MSG.req_error_param_null, "groupIds");
            return response;
        }
        try {
            JSONArray jsonArray = JSONArray.parseArray(groupIds);
            if (CollectionUtils.isEmpty(jsonArray)) {
                response.setMessage(MSG.req_error_param_invalid, "groupIds");
                return response;
            }
            // groupUuid去重
            LinkedHashSet<Long> linkedHashSet = new ManagedSet<>();
            int size = jsonArray.size();
            for (int i = 0; i < size; i++) {
                linkedHashSet.add(jsonArray.getLong(i));
            }
            int index = 1;
            for (Long groupId : linkedHashSet) {
                CustomTreeDO customTreeDO = new CustomTreeDO();
                customTreeDO.setId(groupId);
                customTreeDO.setSortNo(index++);
                updateNotNull(customTreeDO);
            }
            return Response.success(null);
        } catch (Exception e) {
            logger.error("API group sort error", e);
            response.setMessage(MSG.req_error_group_sort_failed);
        }
        return response;
    }

    @Override
    public List<Long> queryAllMenusInCustomTree(String code) {
        Example example = new Example(CustomTreeDO.class);
        example.createCriteria().andEqualTo("code",code);
        Map<Long,List<CustomTreeDO>> pidMap = customTreeDOMapper.selectAll().stream().filter(t -> Objects.nonNull(t.getParentId())).collect(Collectors.groupingBy(CustomTreeDO::getParentId));
        // 全部分组
        List<CustomTreeDO> all = customTreeDOMapper.selectByExample(example);
        Queue<CustomTreeDO> queue = new LinkedList<>();
        queue.addAll(all);
        while(!queue.isEmpty()){
            CustomTreeDO node = queue.poll();
            List<CustomTreeDO> children = pidMap.get(node.getId());
            if(CollectionUtils.isNotEmpty(children)){
                queue.addAll(children);
                all.addAll(children);
            }
        }
        // 分组下全部菜单
        Example customRefExample = new Example(CustomTreeMenuRefDO.class);
        customRefExample.createCriteria().andIn("customTreeId",all.stream().map(CustomTreeDO::getId).collect(Collectors.toList()));
        return customTreeMenuRefDOMapper.selectByExample(customRefExample).stream().map(CustomTreeMenuRefDO::getMenuId).collect(Collectors.toList());
    }

    @Override
    public List<MenuTreeInfo> appMenuTree(String systemCode) {
        // 菜单分组
        List<MenuDO> menuDOS = menuDOMapper.selectByExample(Example.builder(MenuDO.class).andWhere(Sqls.custom().andEqualTo("systemCode", systemCode).andEqualTo("type", MenuConstants.BRANCH)).build());
        log.info("应用：{}下所有菜单分组：{}", systemCode,menuDOS);
        //顶级菜单
        if (ObjectUtil.isEmpty(menuDOS)){
            return null;
        }
        //Map<Long, Long> id2ParentIdMap = customTreeDOList.stream().filter(item->item.getParentId()!=null).collect(Collectors.toMap(CustomTreeDO::getId, CustomTreeDO::getParentId));
        // parentId->id
        Map<Long, List<MenuDO>> partentId2CustomTreeMap = menuDOS.stream().filter(item -> item.getParentId() != null).collect(Collectors.groupingBy(MenuDO::getParentId));
        List<MenuDO> topMenuTreeList = menuDOS.stream().filter(item -> item.getParentId() == null).collect(Collectors.toList());
        List<MenuTreeInfo> result = new ArrayList<>();
        for (MenuDO customTreeDO : topMenuTreeList) {
            MenuTreeInfo menuTreeInfo = buildMenuTreeInfo(customTreeDO,partentId2CustomTreeMap);
            result.add(menuTreeInfo);
        }
        return result;
    }

    @Override
    public void addMenuGroup(MenuGroupAddREQ req) {
        String systemCode = GruulUtil.getSystemCode();
        if (null == systemCode){
            throw new MenuException(CommonErrorEnum.SYSTEM_CODE_MISS);
        }

        List<MenuDO> menuDOS = menuDOMapper.selectByExample(Example.builder(MenuDO.class).andWhere(Sqls.custom().andEqualTo("code", req.getCode()).andEqualTo("systemCode", systemCode)).build());
        if (ObjectUtil.isNotEmpty(menuDOS)){
            throw new MenuException(MenuErrorEnum.MENU_EXISTS_ERROR);
        }
        MenuDO menuDO = new MenuDO();
        menuDO.setGmtCreate(new Date())
                .setGmtModified(new Date())
                .setSystemCode(systemCode)
                .setCode(req.getCode())
                .setName(req.getName())
                .setSortNo(req.getSortNo())
                .setParentId(req.getParentId())
                .setType(MenuConstants.BRANCH)
                .setCreateBy(CustomTreeConstants.DEFAULT_OPERATOR)
                .setUpdateBy(CustomTreeConstants.DEFAULT_OPERATOR)
                .setPath(req.getPath());
        menuDOMapper.insert(menuDO);
    }

    @Override
    public void updateMenuGroup(MenuGroupUpdateREQ req) {
        MenuDO customTreeDO = menuDOMapper.selectByPrimaryKey(req.getCustomTreeId());
        customTreeDO.setName(req.getName())
                .setPath(req.getPath())
                .setCode(req.getCode())
                .setSortNo(req.getSortNo())
                .setGmtModified(new Date());
        menuDOMapper.updateByPrimaryKeySelective(customTreeDO);

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delMenuGroup(MenuGroupDelREQ req) {
        MenuDO menuDO = menuDOMapper.selectByPrimaryKey(req.getCustomTreeId());
        if (null == menuDO){
            throw new MenuException(MenuErrorEnum.MENU_NOT_EXISTS_ERROR);
        }
        // 删除菜单
        menuDOMapper.deleteByPrimaryKey(req.getCustomTreeId());
        log.info("删除菜单 menuId:{}", req.getCustomTreeId());
        // 删除资源包中包含该分组的资源
        resourceDOMapper.deleteByExample(Example.builder(ResourceDO.class).andWhere(Sqls.custom()
                .andEqualTo("systemCode",menuDO.getSystemCode()).andEqualTo("menuCode",menuDO.getCode())).build());
        log.info("删除资源包中相关的菜单资源 menuCode:{},systemCode:{}", menuDO.getCode(),menuDO.getSystemCode());
        String type = menuDO.getType();
        log.info("菜单类型：{}", type);
        if (MenuConstants.BRANCH.equals(type)){
            List<MenuDO> menuDOS = menuDOMapper.selectByExample(Example.builder(MenuDO.class).andWhere(Sqls.custom().andEqualTo("parentId", req.getCustomTreeId())).build());
            for (MenuDO item : menuDOS) {
                delMenuGroup(new MenuGroupDelREQ().setCustomTreeId(item.getId()));
            }
        }else if (MenuConstants.LEAF.equals(type)){
            // 删除菜单下功能接口
            functionDOMapper.deleteByExample(Example.builder(FunctionDO.class).andWhere(Sqls.custom().andEqualTo("menuId", menuDO.getId())).build());
            log.info("删除菜单下功能接口 menuId:{}",menuDO.getId());
        }else {
            throw new MenuException(MenuErrorEnum.UNKNOWN_MENU_TYPE);
        }
    }

    // 菜单组目录
    private MenuTreeInfo buildMenuTreeInfo(MenuDO customTreeDO, Map<Long, List<MenuDO>> partentId2CustomTreeMap) {
        MenuTreeInfo parentInfo = new MenuTreeInfo()
                .setId(customTreeDO.getId())
                .setKey(customTreeDO.getId())
                .setGmtCreate(customTreeDO.getGmtCreate())
                .setGmtModified(customTreeDO.getGmtModified())
                .setCode(customTreeDO.getCode())
                .setTitle(customTreeDO.getName())
                .setName(customTreeDO.getName())
                .setSortNo(customTreeDO.getSortNo())
                .setCreateBy(customTreeDO.getCreateBy())
                .setUpdateBy(customTreeDO.getUpdateBy())
                .setIcon(customTreeDO.getIcon())
                .setSystemCode(customTreeDO.getSystemCode())
                .setPath(customTreeDO.getPath())
                ;

        if (partentId2CustomTreeMap.containsKey(parentInfo.getId())){
            List<MenuDO> customTreeDOList = partentId2CustomTreeMap.get(parentInfo.getId());
            for (MenuDO treeDO : customTreeDOList) {
                parentInfo.addChild(buildMenuTreeInfo(treeDO, partentId2CustomTreeMap));
            }
        }
        return parentInfo;
    }

    private boolean checkParams(CustomTreeDO customTreeDO, Response response) {
        if (StringUtils.isBlank(customTreeDO.getCode())) {
            response.setMessage(MSG.req_error_param_null, "code");
            return true;
        }
        if (StringUtils.isBlank(customTreeDO.getName())) {
            response.setMessage(MSG.req_error_param_null, "name");
            return true;
        }
        if (customTreeDO.getFlag() != null && (customTreeDO.getFlag() != 0 && customTreeDO.getFlag() != 1)) {
            response.setMessage(MSG.req_error_param_tip, "flag", "[0,1]");
            return true;
        }
        return false;
    }
}
